package cn.com.dcsgo.service.impl;

import cn.com.dcsgo.ProductFeignClient;
import cn.com.dcsgo.constant.RedisConst;
import cn.com.dcsgo.enums.SkuType;
import cn.com.dcsgo.exception.UuPreferredException;
import cn.com.dcsgo.model.order.CartInfo;
import cn.com.dcsgo.model.product.SkuInfo;
import cn.com.dcsgo.result.ResultCodeEnum;
import cn.com.dcsgo.service.CartService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * CartServiceImpl
 *
 * @author Dcsgo
 * @since 2025/5/9 10:03
 */
@Service
@RequiredArgsConstructor
public class CartServiceImpl implements CartService {
    private final RedisTemplate redisTemplate;
    private final ProductFeignClient productFeignClient;

    /**
     * 根据 userId 获取 Redis 中关联的购物车的 key
     *
     * @param userId userId
     * @return USER_KEY_PREFIX + userId + USER_CART_KEY_SUFFIX
     */
    private String getCartHashKey(Long userId) {
        return RedisConst.USER_KEY_PREFIX + userId + RedisConst.USER_CART_KEY_SUFFIX;
    }

    /**
     * 设置购物车信息过期时间
     *
     * @param cartHashKey 购物车 hash key
     */
    private void setCartInfoExpire(String cartHashKey) {
        redisTemplate.expire(cartHashKey, RedisConst.USER_CART_EXPIRE, TimeUnit.SECONDS);
    }

    @Override
    public void addItem(Long userId, Long skuId, Integer skuNum) {
        // 查询Redis中是否存在userId关联的购物车信息
        String cartHashKey = getCartHashKey(userId);
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartHashKey);
        CartInfo cartInfo;
        if (Boolean.TRUE.equals(hashOps.hasKey(skuId.toString()))) {
            // 存在：校验skuNum是否超过限购数量并更新userId关联的购物车信息
            cartInfo = hashOps.get(skuId.toString());
            Integer newSkuNum = cartInfo.getSkuNum() + skuNum;
            if (newSkuNum < 1) {
                // 新地购买数量小于1(0 -1) 不合法，不进行后续操作，提前退出
                return;
            }
            if (newSkuNum > cartInfo.getPerLimit()) {
                throw new UuPreferredException(ResultCodeEnum.SKU_LIMIT_ERROR);
            }
            cartInfo.setSkuNum(newSkuNum);
            cartInfo.setCurrentBuyNum(newSkuNum);
            // isChecked 选中状态，添加到购物车中的商品在其展示页面默认选中
            cartInfo.setIsChecked(1);
            cartInfo.setUpdateTime(new Date());
        } else {
            // 不存在：Redis中添加userId关联的购物车信息
            // 封装购物车信息
            cartInfo = new CartInfo();
            SkuInfo skuInfo = productFeignClient.getSkuInfoById(skuId);
            if (skuInfo == null) {
                throw new IllegalArgumentException("skuId: " + skuId + " 的商品不存在");
            }
            cartInfo.setSkuId(skuId);
            cartInfo.setCategoryId(skuInfo.getCategoryId());
            cartInfo.setSkuType(skuInfo.getSkuType());
            cartInfo.setIsNewPerson(skuInfo.getIsNewPerson());
            cartInfo.setUserId(userId);
            cartInfo.setCartPrice(skuInfo.getPrice());
            // 第一次添加到购物车的商品数量只能是1
            cartInfo.setSkuNum(1);
            cartInfo.setCurrentBuyNum(1);
            cartInfo.setSkuType(SkuType.COMMON.getCode());
            cartInfo.setPerLimit(skuInfo.getPerLimit());
            cartInfo.setImgUrl(skuInfo.getImgUrl());
            cartInfo.setSkuName(skuInfo.getSkuName());
            cartInfo.setWareId(skuInfo.getWareId());
            cartInfo.setIsChecked(1);
            cartInfo.setStatus(1);
            cartInfo.setCreateTime(new Date());
            cartInfo.setUpdateTime(new Date());
        }
        // 更新redis
        hashOps.put(skuId.toString(), cartInfo);
        // 设置购物车信息的过期时间
        setCartInfoExpire(cartHashKey);
    }

    @Override
    public void removeItem(Long userId, Long skuId) {
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(getCartHashKey(userId));
        if (Boolean.TRUE.equals(hashOps.hasKey(skuId.toString()))) {
            hashOps.delete(skuId.toString());
        }
    }

    @Override
    public void removeItem(Long userId, List<Long> skuIdList) {
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(getCartHashKey(userId));
        skuIdList.forEach(skuId -> hashOps.delete(skuId.toString()));
    }

    @Override
    public void clear(Long userId) {
        redisTemplate.delete(getCartHashKey(userId));
    }

    @Override
    public List<CartInfo> getItems(Long userId) {
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(getCartHashKey(userId));
        List<CartInfo> cartInfoList = hashOps.values();
        // 按创建时间进行排序 后添加的靠前
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            cartInfoList.sort((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime()));
        }
        return cartInfoList;
    }
}
